﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LeMigue.TeamPortal.Base.Biz.Interface;
using LeMigue.Scrum.Iterface.Model;
using LeMigue.TeamPortal.Base.View;
using LeMigue.Scrum.Iterface.Enum;
using LeMigue.Scrum.Iterface.Service;
using LeMigue.TeamPortal.Base.Service;

namespace LeMigue.TeamPortal.Base.Biz.Implement
{
    public class ScrumBoardBiz : IScrumBoardBiz
    {
        private ITaskBiz TaskBiz = FactoryBiz.TaskBiz;
        private ISprintService SprintService = FactoryService.SprintService;
        private IItemBacklogService BacklogService = FactoryService.ItemBacklogService;
        private IBugService BugService = FactoryService.BugService;

        public IList<IItemListBoardView> ListItemBoard(Sprint sprint)
        {
            List<IItemListBoardView> itensBacklog = sprint.Backlogs.Select(i => (IItemListBoardView)new ItemBacklogView(i)).ToList();

            itensBacklog.AddRange(sprint.Bugs.Select(i => (IItemListBoardView)new BugView(i)).ToList());

            return itensBacklog;
        }

        public IList<IItemListBoardView> ListItemBoard(IItemListBoardView itemBoard)
        {
            List<IItemListBoardView> itensBacklog = ((IHasBacklog)itemBoard.Reference).Backlogs.Select(i => (IItemListBoardView)new ItemBacklogView(i)).ToList();

            return itensBacklog;
        }

        public IList<TaskView> Tasks(IItemListBoardView itemBoard, TaskState? state)
        {
            IList<TaskView> tasks = TaskBiz.List((IHasTask)itemBoard.Reference, state);
            
            return tasks;
        }

        public Sprint SprintAtivo(Team team, int id)
        {
            //TODO: deixar o sprint que está trabalhando no cache?? problema de manter os objetos no cache também
            Sprint sprintAtual;
            if (id == 0)
            {
                IList<Sprint> sprints = SprintService.List(team);
                sprintAtual = sprints.SingleOrDefault(s => s.Atual);
                if (sprintAtual == null)
                    sprintAtual = sprints.SingleOrDefault(s => s.End == sprints.Max(sm => sm.End));
            }
            else
            {
                sprintAtual = SprintService.Load(id);
                //TODO: tratar erro caso não encontre o sprint escolhido
            }

            //TODO: tratar o erro que terá quando não tiver uma data definida;

            return sprintAtual;
        }


        public IItemListBoardView ItemBoard(int? id)
        {
            //TODO: tratar este lance do null
            //TODO: talvez jogar na biz de bug e backlog
            //TODO: derrepente receber mais um parametro que indique o tipo que deverá criar
            if (!id.HasValue)
                return null;

            ItemBacklog itemBacklog = BacklogService.Load(id.Value);
            if (itemBacklog != null)
                return new ItemBacklogView(itemBacklog);

            Bug itemBug = BugService.Load(id.Value);
            if (itemBug != null)
                return new BugView(itemBug);

            return null;
        }
    }
}
